package com.minimalist.tc.manager;

import cn.hutool.core.util.StrUtil;
import com.minimalist.common.entity.tc.entity.po.TcOrder;
import com.minimalist.common.entity.tc.entity.po.TcPlateNumber;
import com.minimalist.common.utils.ImageService;
import com.minimalist.common.utils.UnqIdUtil;
import com.minimalist.tc.mapper.TcOrderMapper;
import com.minimalist.tc.mapper.TcPlateNumberMapper;
import com.mybatisflex.core.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * @author 11987
 */
@Component
public class TcManager{
    @Autowired
    private TcOrderMapper tcOrderMapper;

    @Autowired
    private TcPlateNumberMapper tcPlateNumberMapper;

    @Autowired
    private ImageService imageService;

    // 图片保存路径
    private static final String IMAGE_SAVE_PATH = "D:\\projects\\zhixin\\minimalist-saas\\images\\plateNumbers";

    /**
     * 查询一条未被识别的车牌信息
     *
     * @return 未被识别的车牌信息
     */
    public TcPlateNumber selectNotRecognizePlateNumber(){
        // 查询识别结果为空的车牌信息
        QueryWrapper queryWrapper = QueryWrapper.create()
                .isNull(TcPlateNumber::getIdentifyResult)
                .orderBy(TcPlateNumber::getPlateNumberId, true)
                .limit(1);

        return tcPlateNumberMapper.selectOneByQuery(queryWrapper);
    }

    /**
     * 查询指定数量未被识别的车牌信息
     *
     * @param count 查询数量
     * @return 未被识别的车牌信息列表
     */
    public List<TcPlateNumber> selectNotRecognizePlateNumbers(Integer count){
        // 查询识别结果为空的车牌信息
        QueryWrapper queryWrapper = QueryWrapper.create()
                .isNull(TcPlateNumber::getIdentifyResult)
                .orderBy(TcPlateNumber::getPlateNumberId, true)
                .limit(count);

        return tcPlateNumberMapper.selectListByQuery(queryWrapper);
    }

    /**
     * 从订单表中查询指定数量的车牌号，并检查这些车牌是否已在车牌表中存在且已识别
     * 如果不存在或未识别，则返回这些车牌信息
     *
     * @param count 查询数量
     * @return 未在车牌表中识别的订单车牌信息列表
     */
    public List<String> selectPlateNumbersFromOrderNotInPlateNumber(Integer count){
        // 使用QueryWrapper构建子查询，查找已存在且已识别的车牌
        QueryWrapper subQuery = QueryWrapper.create()
                .select(TcPlateNumber::getPlateNumberName)
                .from(TcPlateNumber.class)
                .isNotNull(TcPlateNumber::getIdentifyResult);

        // 主查询：查找订单表中的车牌号，但不在已识别的车牌列表中
        QueryWrapper queryWrapper = QueryWrapper.create()
                .select("DISTINCT plate_number")
                .from(TcOrder.class)
                .isNotNull(TcOrder::getPlateNumber)
                .notIn(TcOrder::getPlateNumber, subQuery)
                .orderBy(TcOrder::getCreateTime, false)
                .limit(count);

        // 执行查询并返回结果
        return tcOrderMapper.selectListByQuery(queryWrapper).stream().map(TcOrder::getPlateNumber).toList();
    }

    /**
     * 从订单表中获取指定数量未被识别的车牌，并插入到车牌表中
     * 同时下载对应的车牌图片
     *
     * @param count 获取数量
     * @return 插入的车牌数量
     */
    @Transactional(rollbackFor = Exception.class)
    public int insertPlateNumbersFromOrder(Integer count){
        // 获取订单表中存在但在车牌表中不存在或未识别的车牌号
        List<String> plateNumbers = selectPlateNumbersFromOrderNotInPlateNumber(count);

        if (plateNumbers == null || plateNumbers.isEmpty()){
            return 0;
        }

        // 批量插入车牌信息
        List<TcPlateNumber> plateNumberList = new ArrayList<>();
        for (String plateNumber : plateNumbers){
            // 检查车牌是否已存在
            TcPlateNumber existPlateNumber = tcPlateNumberMapper.selectPlateNumberByPlateNumberName(plateNumber);
            if (existPlateNumber == null){
                // 查询订单信息，获取图片URL
                TcOrder order = getOrderByPlateNumber(plateNumber);
                Long fileId = null;

                // 如果找到订单且有图片URL，则下载图片
                if (order != null && StrUtil.isNotBlank(order.getPictureUrl())){
                    fileId = downloadPlateNumberImages(plateNumber, order.getPictureUrl());
                }

                // 创建新的车牌记录
                TcPlateNumber newPlateNumber = TcPlateNumber.builder()
                        .plateNumberId(UnqIdUtil.uniqueId())
                        .plateNumberName(plateNumber)
                        .fileId(fileId) // 设置文件ID
                        .build();
                plateNumberList.add(newPlateNumber);
            } // 车牌已存在但未识别，不需要处理
        }

        // 批量插入
        if (!plateNumberList.isEmpty()){
            tcPlateNumberMapper.insertBatch(plateNumberList);
        }

        return plateNumberList.size();
    }

    /**
     * 根据车牌号查询最新的订单信息
     *
     * @param plateNumber 车牌号
     * @return 订单信息
     */
    private TcOrder getOrderByPlateNumber(String plateNumber){
        QueryWrapper queryWrapper = QueryWrapper.create()
                .eq(TcOrder::getPlateNumber, plateNumber)
                .orderBy(TcOrder::getCreateTime, false)
                .limit(1);

        return tcOrderMapper.selectOneByQuery(queryWrapper);
    }

    /**
     * 下载车牌图片
     *
     * @param plateNumber 车牌号
     * @param pictureUrl  图片URL，可能包含多个URL，以逗号分隔
     * @return 文件ID（这里简单返回时间戳作为文件ID）
     */
    private Long downloadPlateNumberImages(String plateNumber, String pictureUrl){
        if (StrUtil.isBlank(pictureUrl)){
            return null;
        }

        // 生成文件ID
        long fileId = UnqIdUtil.uniqueId();

        try{
            // 分割URL
            String[] urls = pictureUrl.split(",");

            // 创建以fileId命名的文件夹
            String folderPath = IMAGE_SAVE_PATH + "\\" + fileId;
            java.io.File folder = new java.io.File(folderPath);
            if (!folder.exists()){
                boolean created = folder.mkdirs();
                if (!created){
                    System.err.println("创建文件夹失败: " + folderPath);
                    return null;
                }
            }

            // 下载所有图片
            boolean atLeastOneSuccess = false;
            for (int i = 0; i < urls.length; i++){
                String url = urls[i].trim();
                // 确保URL格式正确
                if (!url.startsWith("http")){
                    url = "http://59.57.7.8:8081/jjajxadmin-bucket/upload/upload_park/" + url;
                }

                // 构建保存路径，使用索引作为文件名
                String savePath = folderPath + "\\" + plateNumber + "_" + (i + 1) + ".jpg";

                // 下载图片 - 现在downloadImage不会抛出异常
                String result = imageService.downloadImage(url, savePath);
                if (result != null){
                    atLeastOneSuccess = true;
                }
            }

            // 如果至少有一张图片下载成功，则返回fileId
            return atLeastOneSuccess ? fileId : null;
        } catch (Exception e){
            // 捕获所有可能的异常，确保不影响Excel导入流程
            System.err.println("下载车牌图片过程中发生错误: " + e.getMessage());
            return null;
        }
    }

    /**
     * 检查车牌是否已被识别，如果未被识别则插入车牌表并下载图片
     *
     * @param order 订单信息
     */
    public void checkAndInsertPlateNumber(TcOrder order){
        if (order == null || StrUtil.isBlank(order.getPlateNumber())){
            return;
        }

        String plateNumber = order.getPlateNumber();

        // 查询车牌是否已存在且已识别
        TcPlateNumber existPlateNumber = tcPlateNumberMapper.selectPlateNumberByPlateNumberName(plateNumber);

        // 如果车牌不存在或未识别，则插入车牌表
        if (existPlateNumber == null){
            Long fileId = null;

            // 如果有图片URL，则下载图片
            if (StrUtil.isNotBlank(order.getPictureUrl())){
                fileId = downloadPlateNumberImages(plateNumber, order.getPictureUrl());
            }

            // 创建新的车牌记录
            TcPlateNumber newPlateNumber = TcPlateNumber.builder()
                    .plateNumberId(UnqIdUtil.uniqueId())
                    .plateNumberName(plateNumber)
                    .fileId(fileId) // 设置文件ID
                    .build();

            // 插入车牌表
            tcPlateNumberMapper.insert(newPlateNumber);
        }
    }
}
